package com.zijidelu.luframework.infrastructure.persistence.repository.core.base;

import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.zijidelu.luframework.utils.CastUtil;
import com.zijidelu.luframework.base.model.DataModel;
import com.zijidelu.luframework.base.model.PO;
import com.zijidelu.luframework.infrastructure.converter.DataConverter;
import com.zijidelu.luframework.infrastructure.persistence.repository.core.criteria.PersistenceContext;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 数据仓库最顶层抽象类.
 *
 * @author ZIJIDELU
 * @date: 2024/3/21 21:35
 */
public abstract class AbstractRepository<
        P extends PO,
        D extends DataModel
        > implements Repository<P, D> {

    /**
     * 实体类型。
     */
    protected final Class<P> poClass = CastUtil.cast(ReflectionKit.getSuperClassGenericType(
            this.getClass(),
            AbstractRepository.class, 0)
    );

    /**
     * DTO类型。
     */
    protected final Class<D> dtoClass = CastUtil.cast(ReflectionKit.getSuperClassGenericType(
            this.getClass(),
            AbstractRepository.class, 1)
    );

    /**
     * 转换器。
     */
    @Autowired
    private ObjectProvider<DataConverter<P, D>> dataConverterProvider;
    protected DataConverter<P, D> dataConverter;

    @Autowired
    private ObjectProvider<PersistenceContext<P>> persistenceContextProvider;
    private PersistenceContext<P> persistenceContext;


    @Override
    public Class<D> getDtoClass() {
        return dtoClass;
    }

    @Override
    public Class<P> getPoClass() {
        return poClass;
    }

    @Override
    public DataConverter<P, D> getDataConverter() {
        if (dataConverter == null) {
            dataConverter = dataConverterProvider.stream().findFirst().orElseThrow();
        }

        return dataConverter;
    }

    @Override
    public PersistenceContext<P> getPersistenceContext() {
        if (persistenceContext == null) {
            persistenceContext = persistenceContextProvider.getIfAvailable();
        }

        return persistenceContext;
    }


}
